package com.ayu.commentbackend.service.impl;

import com.ayu.commentbackend.properties.JwtProperties;
import com.ayu.commentbackend.mapper.BlogMapper;
import com.ayu.commentbackend.mapper.UserMapper;
import com.ayu.commentbackend.pojo.entity.User;
import com.ayu.commentbackend.pojo.result.Result;
import com.ayu.commentbackend.service.UserService;
import com.ayu.commentbackend.utils.JwtUtil;
import com.ayu.commentbackend.utils.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    JwtProperties jwtProperties;
    @Autowired
    BlogMapper blogMapper;

    @Override
    public void register(User user) {
        // 对密码进行 MD5 加密
        String md5Pwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pwd);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());

        // 插入时可能会出现用户名重复的问题，已在全局异常处理类中处理
        userMapper.insert(user);
    }

    @Override
    public Result login(User user) {
        try {
            User userInDB = userMapper.getUserByUsername(user.getUsername());
            String md5Pwd = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
            if(!userInDB.getPassword().equals(md5Pwd)) {
                return Result.error("密码错误");
            }
            // 密码正确，生成token并返回
            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", userInDB.getId());
            claims.put("version", userInDB.getVersion());
            String token = JwtUtil.createJWT(
                    jwtProperties.getUserSecretKey(),
                    jwtProperties.getUserTtl(),
                    claims);
            return Result.success(token);

        } catch (Exception ex){
            log.error("未查询到名为“"+user.getUsername()+"”的用户");
            return Result.error("用户不存在");
        }
    }

    @Override
    public Result updatePwd(Map<String, String> params) {
        String oldPassword = params.get("oldPassword");
        String newPassword = params.get("newPassword");
        String rePassword = params.get("rePassword");

        if(!StringUtils.hasLength(oldPassword) ||
                !StringUtils.hasLength(newPassword) ||
                !StringUtils.hasLength(rePassword)) {
            return Result.error("参数填写不完整");
        }

        if(!newPassword.equals(rePassword)) {
            return Result.error("两次输入的新密码不一致");
        }

        User userInDB;
        try{
            userInDB = userMapper.getUserById(ThreadLocalUtil.getCurrentId());
        } catch (Exception ex){
            log.error(ex.getMessage());
            return Result.error("用户不存在");
        }

        String md5OldPwd = DigestUtils.md5DigestAsHex(oldPassword.getBytes());
        if(!md5OldPwd.equals(userInDB.getPassword())) {
            return Result.error("旧密码错误");
        }

        String md5NewPwd = DigestUtils.md5DigestAsHex(newPassword.getBytes());
        if(userInDB.getPassword().equals(md5NewPwd)){
            return Result.error("新密码不能与旧密码一致");
        }else{
            // 更新密码时同步更新version，使旧令牌立即失效
            userMapper.updatePwd(md5NewPwd,userInDB.getVersion()+1, userInDB.getId());
            return Result.success("密码修改成功");
        }
    }

    @Transactional
    @Override
    public void update(Map<String, Object> params) {
        // TODO 从jwt获取ID
        // user.setId()
        User user = new User();
        user.setId(Long.valueOf((Integer) params.get("id")));
        user.setUpdateTime(LocalDateTime.now());
        user.setUsername((String) params.get("username"));
        user.setAvatar((String) params.get("avatar"));
        userMapper.update(user);

        // 同步修改blog表中的用户名
        blogMapper.updateUsername(user.getUsername(), user.getId());
    }

    @Override
    public User getUserById(Long id) {
        User user = userMapper.getUserById(id);
        user.setPassword("");
        return user;
    }
}
